home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGMISC
/
XLISP.LZH
/
XLISPSRC.ARC
/
XLBFUN.C
< prev
next >
Wrap
Text File
|
1986-05-17
|
10KB
|
450 lines
/* xlbfun.c - xlisp basic built-in functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern NODE *xlenv;
extern NODE *s_evalhook,*s_applyhook;
extern NODE *s_car,*s_cdr,*s_nth,*s_get,*s_svalue,*s_splist,*s_aref;
extern NODE *s_lambda,*s_macro;
extern NODE *s_comma,*s_comat;
extern NODE *s_unbound;
extern char gsprefix[];
extern int gsnumber;
/* external routines */
extern NODE *xlxeval();
/* forward declarations */
FORWARD NODE *bquote1();
FORWARD NODE *defun();
FORWARD NODE *makesymbol();
/* xeval - the built-in function 'eval' */
NODE *xeval(args)
NODE *args;
{
NODE *expr;
/* get the expression to evaluate */
expr = xlarg(&args);
xllastarg(args);
/* evaluate the expression */
return (xleval(expr));
}
/* xapply - the built-in function 'apply' */
NODE *xapply(args)
NODE *args;
{
NODE ***oldstk,*fun,*arglist,*val;
/* create a new stack frame */
oldstk = xlstack;
xlsave1(fun);
/* get the function and argument list */
fun = xlarg(&args);
arglist = xlmatch(LIST,&args);
xllastarg(args);
/* if the function is a symbol, get its value */
if (symbolp(fun))
fun = xleval(fun);
/* apply the function to the arguments */
val = xlapply(fun,arglist);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression evaluated */
return (val);
}
/* xfuncall - the built-in function 'funcall' */
NODE *xfuncall(args)
NODE *args;
{
NODE ***oldstk,*fun,*val;
/* create a new stack frame */
oldstk = xlstack;
xlsave1(fun);
/* get the function (the rest of the args is the argument list) */
fun = xlarg(&args);
/* if the function is a symbol, get its value */
if (symbolp(fun))
fun = xleval(fun);
/* apply the function to the arguments */
val = xlapply(fun,args);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression evaluated */
return (val);
}
/* xset - built-in function set */
NODE *xset(args)
NODE *args;
{
NODE *sym,*val;
/* get the symbol and new value */
sym = xlmatch(SYM,&args);
val = xlarg(&args);
xllastarg(args);
/* assign the symbol the value of argument 2 and the return value */
setvalue(sym,val);
/* return the result value */
return (val);
}
/* xgensym - generate a symbol */
NODE *xgensym(args)
NODE *args;
{
char sym[STRMAX+1];
NODE *x;
/* get the prefix or number */
if (args) {
x = xlarg(&args);
switch (ntype(x)) {
case STR:
strcpy(gsprefix,getstring(x));
break;
case INT:
gsnumber = getfixnum(x);
break;
default:
xlerror("bad argument type",x);
}
}
xllastarg(args);
/* create the pname of the new symbol */
sprintf(sym,"%s%d",gsprefix,gsnumber++);
/* make a symbol with this print name */
return (xlmakesym(sym,DYNAMIC));
}
/* xmakesymbol - make a new uninterned symbol */
NODE *xmakesymbol(args)
NODE *args;
{
return (makesymbol(args,FALSE));
}
/* xintern - make a new interned symbol */
NODE *xintern(args)
NODE *args;
{
return (makesymbol(args,TRUE));
}
/* makesymbol - make a new symbol */
LOCAL NODE *makesymbol(args,iflag)
NODE *args; int iflag;
{
char *pname;
/* get the print name of the symbol to intern */
pname = getstring(xlmatch(STR,&args));
xllastarg(args);
/* make the symbol */
return (iflag ? xlenter(pname,DYNAMIC) : xlmakesym(pname,DYNAMIC));
}
/* xsymname - get the print name of a symbol */
NODE *xsymname(args)
NODE *args;
{
NODE *sym;
/* get the symbol */
sym = xlmatch(SYM,&args);
xllastarg(args);
/* return the print name */
return (getpname(sym));
}
/* xsymvalue - get the value of a symbol */
NODE *xsymvalue(args)
NODE *args;
{
NODE *sym,*val;
/* get the symbol */
sym = xlmatch(SYM,&args);
xllastarg(args);
/* get the global value */
while ((val = getvalue(sym)) == s_unbound)
xlcerror("try evaluating symbol again","unbound variable",sym);
/* return its value */
return (val);
}
/* xsymplist - get the property list of a symbol */
NODE *xsymplist(args)
NODE *args;
{
NODE *sym;
/* get the symbol */
sym = xlmatch(SYM,&args);
xllastarg(args);
/* return the property list */
return (getplist(sym));
}
/* xget - get the value of a property */
NODE *xget(args)
NODE *args;
{
NODE *sym,*prp;
/* get the symbol and property */
sym = xlmatch(SYM,&args);
prp = xlmatch(SYM,&args);
xllastarg(args);
/* retrieve the property value */
return (xlgetprop(sym,prp));
}
/* xputprop - set the value of a property */
NODE *xputprop(args)
NODE *args;
{
NODE *sym,*val,*prp;
/* get the symbol and property */
sym = xlmatch(SYM,&args);
val = xlarg(&args);
prp = xlmatch(SYM,&args);
xllastarg(args);
/* set the property value */
xlputprop(sym,val,prp);
/* return the value */
return (val);
}
/* xremprop - remove a property value from a property list */
NODE *xremprop(args)
NODE *args;
{
NODE *sym,*prp;
/* get the symbol and property */
sym = xlmatch(SYM,&args);
prp = xlmatch(SYM,&args);
xllastarg(args);
/* remove the property */
xlremprop(sym,prp);
/* return nil */
return (NIL);
}
/* xhash - compute the hash value of a string or symbol */
NODE *xhash(args)
NODE *args;
{
char *str;
NODE *val;
int len;
/* get the string and the table length */
val = xlarg(&args);
len = (int)getfixnum(xlmatch(INT,&args));
xllastarg(args);
/* get the string */
if (symbolp(val))
str = getstring(getpname(val));
else if (stringp(val))
str = getstring(val);
else
xlerror("bad argument type",val);
/* return the hash index */
return (cvfixnum((FIXNUM)hash(str,len)));
}
/* xaref - array reference function */
NODE *xaref(args)
NODE *args;
{
NODE *array,*index;
int i;
/* get the array and the index */
array = xlmatch(VECT,&args);
index = xlmatch(INT,&args); i = (int)getfixnum(index);
xllastarg(args);
/* range check the index */
if (i < 0 || i >= getsize(array))
xlerror("array index out of bounds",index);
/* return the array element */
return (getelement(array,i));
}
/* xmkarray - make a new array */
NODE *xmkarray(args)
NODE *args;
{
int size;
/* get the size of the array */
size = (int)getfixnum(xlmatch(INT,&args));
xllastarg(args);
/* create the array */
return (newvector(size));
}
/* xerror - special form 'error' */
NODE *xerror(args)
NODE *args;
{
char *emsg; NODE *arg;
/* get the error message and the argument */
emsg = getstring(xlmatch(STR,&args));
arg = (args ? xlarg(&args) : s_unbound);
xllastarg(args);
/* signal the error */
xlerror(emsg,arg);
}
/* xcerror - special form 'cerror' */
NODE *xcerror(args)
NODE *args;
{
char *cmsg,*emsg; NODE *arg;
/* get the correction message, the error message, and the argument */
cmsg = getstring(xlmatch(STR,&args));
emsg = getstring(xlmatch(STR,&args));
arg = (args ? xlarg(&args) : s_unbound);
xllastarg(args);
/* signal the error */
xlcerror(cmsg,emsg,arg);
/* return nil */
return (NIL);
}
/* xbreak - special form 'break' */
NODE *xbreak(args)
NODE *args;
{
char *emsg; NODE *arg;
/* get the error message */
emsg = (args ? getstring(xlmatch(STR,&args)) : "**BREAK**");
arg = (args ? xlarg(&args) : s_unbound);
xllastarg(args);
/* enter the break loop */
xlbreak(emsg,arg);
/* return nil */
return (NIL);
}
/* xcleanup - special form 'clean-up' */
NODE *xcleanup(args)
NODE *args;
{
xllastarg(args);
xlcleanup();
}
/* xtoplevel - special form 'top-level' */
NODE *xtoplevel(args)
NODE *args;
{
xllastarg(args);
xltoplevel();
}
/* xcontinue - special form 'continue' */
NODE *xcontinue(args)
NODE *args;
{
xllastarg(args);
xlcontinue();
}
/* xevalhook - eval hook function */
NODE *xevalhook(args)
NODE *args;
{
NODE ***oldstk,*expr,*ehook,*ahook,*oldenv;
NODE *newehook,*newahook,*newenv,*val;
/* create a new stack frame */
oldstk = xlstack;
xlstkcheck(4);
xlsave(ehook);
xlsave(ahook);
xlsave(oldenv);
xlsave(newenv);
/* get the expression, the new hook functions and the environment */
expr = xlarg(&args);
newehook = xlarg(&args);
newahook = xlarg(&args);
newenv = (args ? xlarg(&args) : xlenv);
xllastarg(args);
/* bind *evalhook* and *applyhook* to the hook functions */
ehook = getvalue(s_evalhook);
setvalue(s_evalhook,newehook);
ahook = getvalue(s_applyhook);
setvalue(s_applyhook,newahook);
oldenv = xlenv;
xlenv = newenv;
/* evaluate the expression (bypassing *evalhook*) */
val = xlxeval(expr);
/* unbind the hook variables */
setvalue(s_evalhook,ehook);
setvalue(s_applyhook,ahook);
xlenv = oldenv;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}